package org.tity.commons.machine;

import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.util.Enumeration;

import org.tity.commons.encrypt.MD5Util;
import org.tity.commons.log.Logger;

import oshi.SystemInfo;
import oshi.hardware.CentralProcessor;
import oshi.hardware.HardwareAbstractionLayer;
import oshi.software.os.NetworkParams;
import oshi.software.os.OperatingSystem;

/**
 * @author fangjieli 
 * 获得服务器相关信息
 * */
public class Machine {
 
	/**
	 * 获得主机名
	 * @return 主机名
	 * */
	public static String getHostName() {
		try {
			initIf();
		} catch (Exception e) {
			Logger.exception(e);
		}
		return hostName;
	}
	
	/**
	 * 获得主机ID
	 * @return 主机唯一标识
	 * */
	public static String getIdentity() {
		try {
			initIf();
		} catch (Exception e) {
			Logger.exception(e);
		}
		return machineId;
	}
	
	/**
	 * 获得主机Mac地址
	 * @return mac地址
	 * */
	public static String getMacAddress() {
		try {
			initIf();
		} catch (Exception e) {
			Logger.exception(e);
		}
		return macAddress;
	}
	
	/**
	 * 获得主机ip地址
	 * @return ip地址
	 * */
	public static String getIp() {
		try {
			initIf();
		} catch (Exception e) {
			Logger.exception(e);
		}
		return ip;
	}
	
	private static String machineId=null;
	private static String hostName=null;
	private static String macAddress=null;
	private static String ip=null;
	
	/**
	 * 获得机器的唯一ID，支持虚机、docker
	 * @throws SocketException 
	 * */
	private static String initIf() throws Exception {
		if(machineId!=null) {
			return machineId;
		}
		SystemInfo si = new SystemInfo();
		HardwareAbstractionLayer hal = si.getHardware();
		CentralProcessor processor = hal.getProcessor();
		String serial="cpu:"+processor.getProcessorID()+"|"+processor.toString();
		serial=MD5Util.encrypt16(serial);
		machineId=serial;
		
		
		InetAddress addr = InetAddress.getLocalHost();
		ip=addr.getHostAddress().toString();
		macAddress=getMacAddressInternal();
		 
		
		 OperatingSystem os = si.getOperatingSystem();
		 NetworkParams np=os.getNetworkParams();
		 hostName=np.getHostName();
 
	
		return serial;
	}
	
//	public static void main(String[] args) throws SocketException {
//		System.out.println(getIdentity());
////		Set<NetworkInterface>niset=NetworkUtil.getPhysicalNICs();
////		for (NetworkInterface ni : niset) {
////			System.out.println(ni.getDisplayName()+","+ni.getName()+","+ni.isUp()+","+ni.isVirtual());
////		}
////		/System.out.println(NetworkUtil.get);
//	}
	
	private static String getMacAddressInternal() {
        try {
            Enumeration<NetworkInterface> allNetInterfaces = NetworkInterface.getNetworkInterfaces();
            byte[] mac = null;
            while (allNetInterfaces.hasMoreElements()) {
                NetworkInterface netInterface = (NetworkInterface) allNetInterfaces.nextElement();
                if (netInterface.isLoopback() || netInterface.isVirtual() || netInterface.isPointToPoint() || !netInterface.isUp()) {
                    continue;
                } else {
                    mac = netInterface.getHardwareAddress();
                    if (mac != null) {
                        StringBuilder sb = new StringBuilder();
                        for (int i = 0; i < mac.length; i++) {
                            sb.append(String.format("%02X%s", mac[i], (i < mac.length - 1) ? "-" : ""));
                        }
                        if (sb.length() > 0) {
                            return sb.toString();
                        }
                    }
                }
            }
        } catch (Exception e) {
            Logger.error("MAC地址获取失败", e);
        }
        return "";
    }
	
	public static void main(String[] args) throws Exception {
        InetAddress addr = InetAddress.getLocalHost();  
        String ip=addr.getHostAddress().toString(); //获取本机ip  
        String hostName=addr.getHostName().toString(); //获取本机计算机名称  
        System.out.println(ip);
        System.out.println(hostName);
        System.out.println(getMacAddressInternal());
   }
	
}
